
const {
    logger,
    sleep,
    httpGet,
    set,
    get,
    expire,
    httpPost,
    avoidNoticeFreq,
    easyPushWechatMsg,
    hset,
    hgetall,
    hdel,
} = require('./util');

const {
    syncExec,
} = require('./model');

const {
    readTask,
} = require('./ti_logic_read_task');

process.on('unhandledRejection', error => {
    logger('unhandledRejection', error)
});

let openSerials = [];//需要关注的规格
(async () => {//每10分钟重新拉取任务列表
    while (1) {
        logger('读取任务列表');
        const tasks = await readTask();
        if (!tasks) continue;
        const tmpSerials = [];
        for (const task of tasks) {
            if (task.status != 1) continue;
            tmpSerials.push(task.serial);
        }
        openSerials = tmpSerials;
        logger('任务数量', openSerials.length);
        await sleep(600000);
    }
})();

let forecastSerials = [];//当天可能补货的规格
(async () => {//每10分钟拉取预测规格
    while (openSerials.length == 0) {
        await sleep(1000);
    }

    logger('查询补货时间');
    const url = "https://www.ti.com.cn/productmodel/opn/stockforecast?locale=zh-CN";
    const ret = await httpPost(url, JSON.stringify(openSerials), 'application/json');
    logger('补货时间结果', ret);
    const retJson = JSON.parse(ret);
    const now = new Date().getTime();
    for (const serial in retJson) {
        const v = retJson[serial];
        const matches = v.forecast.items[0].startDate.match(/(\d+)年 (\d+)月 (\d+)日/);
        const year = matches[1];
        const month = matches[2];
        const date = matches[3];
        const ts = new Date(year+'-'+month+'-'+date+' 00:00:00').getTime();
        if (ts > now) continue;
        await hset('ti_forecast_serial', serial, ts + 86400000 * 7);
    }

    //清理过期规格
    const map = await hgetall('ti_forecast_serial');
    forecastSerials = [];
    for (const serial in map) {
        const ts = map[serial];
        if (ts < now) {
            await hdel('ti_forecast_serial', serial);
        } else {
            forecastSerials.push(serial);
        }
    }

    logger('需要查询的规格为', forecastSerials);
})();

(async () => {

    while (forecastSerials.length == 0) {
        await sleep(1000);
    }

    while (1) {
        for (const serial of forecastSerials) {
            //最近是否成功加过购物车（如果有成功，则6小时内不再尝试）
            const recentSuccKey = 'ti_add_cart_succ_'+serial;
            const isRecentSucc = await get(recentSuccKey);
            if (isRecentSucc) continue;

            const referer = `https://www.ti.com.cn/store/ti/zh/p/product/?p=${encodeURIComponent(serial)}`;
            const url = `https://www.ti.com.cn/storeservices/cart/opninventory?opn=${serial}`;
            let msg;
            let stock;
            try {
                const ret = await httpGet(url, referer);
                const retJson = JSON.parse(ret);
                if (!retJson.hasOwnProperty('inventory')) {
                    logger('未预期的返回内容', serial, ret);
                    continue;
                }
                stock = retJson.inventory;
                if (stock <= 0) {
                    logger('query', serial);
                    continue;
                }

                msg = `预告方案：规格 ${serial} 发现有 ${stock} 库存`;
                logger(msg);
                
                //门槛是250件
                if (stock < 250) continue;
            } catch(e) {
                logger('查询库存出错', serial, e);
                await sleep(5000);
                continue;
            }

            //检测到有库存，发送通知
            if (!await avoidNoticeFreq(serial)) continue;//防止消息轰炸
            await easyPushWechatMsg(msg);

            //处理登录态
            const cookie = await get('ti_worker_cookie');
            const arr = cookie.split(';');
            let chromeVer = 95;
            let ua;
            let platform = '"Windows"';
            arr.map(str => {
                str = str.trim();
                const key = str.substr(0, str.indexOf('='));
                const value = decodeURIComponent(str.substr(str.indexOf('=')+1));
                if (key == 'ti_ua') {//获取ua
                    ua = value;
                    try {
                        chromeVer = ua.match(/Chrome\/(\d+)/)[1];
                    } catch(e){}
        
                    if (ua.indexOf('Mac') > -1) {
                        platform = '"macOS"';
                    }
                }
            });
            const postData = JSON.stringify({
                'cartRequestList':[{
                    'opnId':serial,
                    'packageOption':null,
                    'quantity':Number(stock),
                    'sparam':'',
                    'tiAddtoCartSource':'store-pdp',
                }],
                'currency':'CNY',
            });

            //加购物车，最多重试2次
            let failCount = 0;
            for (let i=0; i<3; i++) {
                const cookie = await get('ti_worker_cookie');

                const cmdStr = `curl --compressed \
                    -H 'Host: www.ti.com.cn' \
                    -H 'Connection: keep-alive' \
                    -H 'sec-ch-ua: "Google Chrome";v="${chromeVer}", "Chromium";v="${chromeVer}", ";Not A Brand";v="99"' \
                    -H 'sec-ch-ua-mobile: ?0' \
                    -H "User-Agent: ${ua}" \
                    -H "Content-Type: application/json" \
                    -H 'X-Sec-Clge-Req-Type: ajax' \
                    -H 'Expires: 0' \
                    -H "Cache-Control: no-store, must-revalidate" \
                    -H 'sec-ch-ua-platform: ${platform}' \
                    -H 'Accept: */*' \
                    -H 'Origin: https://www.ti.com.cn' \
                    -H 'Sec-Fetch-Site: same-origin' \
                    -H 'Sec-Fetch-Mode: cors' \
                    -H 'Sec-Fetch-Dest: empty' \
                    -H 'Referer: ${referer}' \
                    -H 'Accept-Encoding: gzip, deflate, br' \
                    -H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8' \
                    -H 'Cookie: ${cookie}' \
                    -d '${postData}' \
                    https://www.ti.com.cn/occservices/v2/ti/addtocart -v`;

                const cmdRet = await syncExec(cmdStr);
                logger('postData', postData, "\n", cmdStr, "\n", cmdRet);
                if (cmdRet.indexOf('cartId') > -1) {
                    //记录到redis，6小时内不再尝试加购物车
                    await set(recentSuccKey, 1);
                    await expire(recentSuccKey, 3600 * 6);

                    msg = `预告方案：规格 ${serial} 成功添加 ${stock} 件进购物车`;
                    await easyPushWechatMsg(msg);

                    //推送到redis，等待下单脚本进行下单操作
                    await lpush('ti_worker_order', serial);

                    continue;
                } else {
                    failCount++;
                    logger(`加购物车第${failCount}次失败`);
                    msg = `预告方案：规格 ${serial} 加购物车失败,请更换cookie`;
                    await easyPushWechatMsg(msg);
                    await sleep(15000);
                }
            }
        }
    }

})();

